package form

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"shimmer/neusoft_club_backend/controllers/club_controller/form/status"
	"shimmer/neusoft_club_backend/controllers/cons"
	"shimmer/neusoft_club_backend/controllers/utils"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/middlewares/auth_middleware"
	"shimmer/neusoft_club_backend/services"
	"shimmer/neusoft_club_backend/services/club_service"
	"shimmer/neusoft_club_backend/services/errs"
	"strconv"
)

// @Summary 获取社团的所有可用表单
// @Description
// @Tags 社团
// @Param clubID path  integer true "社团ID"
// @Param page query  integer true "页面"
// @Param size query  integer true "页面大小"
// @Success 200 {object} []domain.ClubFormDTO
// @Router /api/club/{clubID}/form [get]
func getClubForms(c *gin.Context) {
	parseInt, err := strconv.ParseInt(c.Param(cons.ClubUriParam), 10, 64)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	pageQuery, err := utils.GetPaginationFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	forms, err := club_service.GetAllClubForms(parseInt, pageQuery)
	if err != nil {
		services.AbortWithDatabaseError(c, err)
		return
	}
	c.JSON(http.StatusOK, forms)
}

// @Summary 获取社团的纳新表单
// @Description
// @Tags 社团
// @Param clubID path  integer true "社团ID"
// @Success 200 {object} domain.ClubFormDTO
// @Router /api/club/{clubID}/form/join [get]
func getJoinClubForm(c *gin.Context) {
	parseInt, err := strconv.ParseInt(c.Param(cons.ClubUriParam), 10, 64)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	form, err := club_service.GetJoinClubForm(parseInt)
	if err != nil {
		return
	}
	c.JSON(http.StatusOK, form)
}

// TODO 增删改查

// @Summary 创建社团表单
// @Description
// @Tags 社团
// @Param clubID path integer true "社团ID"
// @Param value body club_service.ClubFormInfo true "value"
// @Success 200 {object} domain.ClubFormDTO
// @Router /api/club/{clubID}/form [post]
func insertForm(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	clubBinding := &cons.ClubUriParamBinding{}
	if err = c.ShouldBindUri(clubBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	owner, err := club_service.CheckIsClubOwner(user.ID, clubBinding.ClubID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !owner {
		services.AbortWithError(c, errs.ErrNotClubManager)
		return
	}
	info := &club_service.ClubFormInfo{}
	if err = c.ShouldBind(info); err != nil {
		services.AbortWithError(c, err)
		return
	}
	form, err := club_service.UploadClubForm(clubBinding.ClubID, info)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, form)
}

// @Summary 更新社团表单
// @Description
// @Tags 社团
// @Param clubID path integer true "社团ID"
// @Param formID path integer true "表单ID"
// @Param value body club_service.ClubFormInfo true "value"
// @Router /api/club/{clubID}/form/single/{formID} [put]
func updateForm(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	clubBinding := &cons.ClubUriParamBinding{}
	if err = c.ShouldBindUri(clubBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	formBinding := &cons.FormUriParamBinding{}
	if err = c.ShouldBindUri(formBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	owner, err := club_service.CheckIsClubOwner(user.ID, clubBinding.ClubID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !owner {
		services.AbortWithError(c, errs.ErrNotClubManager)
		return
	}
	info := &club_service.ClubFormInfoUpdate{}
	if err = c.ShouldBind(info); err != nil {
		services.AbortWithError(c, err)
		return
	}
	form, err := club_service.UpdateClubForm(formBinding.FormID, info)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, form)
}

// @Summary 删除社团表单
// @Description
// @Tags 社团
// @Param clubID path integer true "社团ID"
// @Param formID path integer true "表单ID"
// @Success 204
// @Router /api/club/{clubID}/form/single/{formID} [delete]
func deleteForm(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	clubBinding := &cons.ClubUriParamBinding{}
	if err = c.ShouldBindUri(clubBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	formBinding := &cons.FormUriParamBinding{}
	if err = c.ShouldBindUri(formBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	owner, err := club_service.CheckIsClubOwner(user.ID, clubBinding.ClubID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !owner {
		services.AbortWithError(c, errs.ErrNotClubManager)
		return
	}
	if err = club_service.DeleteClubForm(formBinding.FormID); err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.AbortWithStatus(http.StatusNoContent)
}

// @Summary 查询单个社团表单信息
// @Description
// @Tags 社团
// @Param clubID path integer true "社团ID"
// @Param formID path integer true "表单ID"
// @Success 200 {object} domain.ClubFormDTO
// @Router /api/club/{clubID}/form/single/{formID} [get]
func findOneClubForm(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	clubBinding := &cons.ClubUriParamBinding{}
	formBinding := &cons.FormUriParamBinding{}
	if err = c.ShouldBindUri(clubBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	if err = c.ShouldBindUri(formBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	in, err := club_service.CheckInClub(user.ID, clubBinding.ClubID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !in {
		services.AbortWithError(c, errs.ErrIsNotClubMember)
		return
	}
	form, err := club_service.FindClubFormInClub(formBinding.FormID, clubBinding.ClubID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, form)
}

func ConfigureClubFormController(r *gin.RouterGroup) {
	{
		statusGroups := r.Group("/status")
		status.ConfigureClubFormStatusController(statusGroups)
	}
	r.GET("/", getClubForms)
	r.GET("/join", getJoinClubForm)
	r.POST("/", auth_middleware.AuthLoginMiddleware(), insertForm)
	r.PUT(fmt.Sprintf("/single/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), updateForm)
	r.DELETE(fmt.Sprintf("/single/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), deleteForm)
	r.GET(fmt.Sprintf("/single/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), findOneClubForm)
	
	r.PUT(fmt.Sprintf("/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), updateForm)
	r.DELETE(fmt.Sprintf("/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), deleteForm)
	r.GET(fmt.Sprintf("/:%s", cons.FormUriParam), auth_middleware.AuthLoginMiddleware(), findOneClubForm)
}
